using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SmartLink.Domain.Entity;
using SmartLink.Domain.IServices;
using SmartLink.IRepository;
using SmartLink.DTOS;
using SmartLink.Infrastructure;
using SmartLink.Domain.ExpandEntity.Base;
using SmartLink.Domain.ExpandEntity;
using SmartLink.EnumLibrary;
using SmartLink.DTOS.Permission;

namespace SmartLink.Domain.Services
{
    /// <summary>
    /// 权限相关都放在这里
    /// </summary>
    public class PermissionServices : IPermissionServices
    {
        //角色
        private IPER_RoleGroupRepo _IPER_RoleGroupRepo;
        //角色-菜单权限
        private IPER_MenuPermissionsRoleRepo _IPER_MenuPermissionsRoleRepo;
        //角色-动作权限
        private IPER_ActionPermissionsRoleRepo _IPER_ActionPermissionsRoleRepo;
        //菜单
        private ISYS_MenuRepo _ISYS_MenuRepo;
        //动作
        private IPER_ActionPermissionsRepo _IPER_ActionPermissionsRepo;
        //数据权限，组织架构（部门）
        private IPER_DataPermissionsRepo _IPER_DataPermissionsRepo;
        //动作权限分组
        private IPER_PermissionsGroupRepo _IPER_PermissionsGroupRepo;
        //用户-角色
        private IPER_UserToRoleRepo _IPER_UserToRoleRepo;


        private IPER_ActionAuthorizationRepo _IPER_ActionAuthorizationRepo;
        private IPER_DataAuthorizationRepo _IPER_DataAuthorizationRepo;
        private ISYS_ModuleRepo _ISYS_ModuleRepo;
        private ISYS_ModuleFunctionRepo _ISYS_ModuleFunctionRepo;

        public PermissionServices(IPER_RoleGroupRepo iPER_RoleGroupRepo,
                                          IPER_MenuPermissionsRoleRepo iPER_MenuPermissionsRoleRepo,
                                          IPER_ActionPermissionsRoleRepo iPER_ActionPermissionsRoleRepo,
                                          ISYS_MenuRepo iSYS_MenuRepo,
                                          IPER_ActionPermissionsRepo iPER_ActionPermissionsRepo,
                                          IPER_PermissionsGroupRepo iPER_PermissionsGroupRepo,
                                          IPER_UserToRoleRepo iPER_UserToRoleRepo,
                                          IPER_DataPermissionsRepo iPER_DataPermissionsRepo,
                                          IPER_ActionAuthorizationRepo iPER_ActionAuthorizationRepo,
                                          IPER_DataAuthorizationRepo iPER_DataAuthorizationRepo,
                                          ISYS_ModuleRepo iSYS_ModuleRepo,
                                          ISYS_ModuleFunctionRepo iSYS_ModuleFunctionRepo
                                          )
        {
            _IPER_RoleGroupRepo = iPER_RoleGroupRepo;
            _IPER_MenuPermissionsRoleRepo = iPER_MenuPermissionsRoleRepo;
            _IPER_ActionPermissionsRoleRepo = iPER_ActionPermissionsRoleRepo;
            _ISYS_MenuRepo = iSYS_MenuRepo;
            _IPER_ActionPermissionsRepo = iPER_ActionPermissionsRepo;
            _IPER_PermissionsGroupRepo = iPER_PermissionsGroupRepo;
            _IPER_UserToRoleRepo = iPER_UserToRoleRepo;
            _IPER_DataPermissionsRepo = iPER_DataPermissionsRepo;
            _IPER_ActionAuthorizationRepo = iPER_ActionAuthorizationRepo;
            _IPER_DataAuthorizationRepo = iPER_DataAuthorizationRepo;
            _ISYS_ModuleRepo = iSYS_ModuleRepo;
            _ISYS_ModuleFunctionRepo = iSYS_ModuleFunctionRepo;
        }

        #region 权限分配

        public void Allot(AuthorizationOwnerTypeEnum ownerType, int ownerId, IEnumerable<int> moduleIds, IEnumerable<int> functionIds)
        {
            _IPER_ActionAuthorizationRepo.Allot(ownerType, ownerId, moduleIds, functionIds);
        }

        public void Allot(AuthorizationOwnerTypeEnum ownerType, int ownerId, IEnumerable<int> moduleIds, IEnumerable<int> functionIds, Dictionary<string, IEnumerable<DataAuthorizationItemDTO>> dataAuthorizations)
        {
            _IPER_ActionAuthorizationRepo.Allot(ownerType, ownerId, moduleIds, functionIds, dataAuthorizations);
        }

        //给角色分配菜单
        public bool AllotMenuIdToRole(bool isOrgManager, int roleId, IList<int> menuIds)
        {
            IList<int> roleIds = new List<int>();
            if (isOrgManager)
                roleIds = _IPER_RoleGroupRepo.GetOrgMangerRoleIds();
            else
                roleIds.Add(roleId);
            return _IPER_UserToRoleRepo.AllotMenuIdToRole(roleIds, menuIds);
        }
        //给角色分配动作权限
        public bool AllotActionsToRole(int roleId, IList<int> actions)
        {
            return _IPER_ActionPermissionsRoleRepo.AllotActionsToRole(roleId, actions);
        }
        //给角色分配数据权限
        public bool AllotDataRightsToRole(int roleId, IList<int> dataRights)
        {
            return _IPER_DataPermissionsRepo.AllotDataRightsToRole(roleId, dataRights);
        }
        #endregion 

        public IList<PER_UserToRole> GetRoleUsers(int roleId)
        {
            return _IPER_UserToRoleRepo.GetRoleUsers(roleId);
        }


        /// <summary>
        /// 供登录调用获取动作权限
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>/
        public IList<PER_ActionPermissions> GetActionPermissionsByUserId(int userId)
        {
            return _IPER_ActionPermissionsRepo.GetActionPermissionsByUserId(userId);
        }

        /// <summary>
        /// 获取所有的行为权限，主要是获得对应行为权限的名字
        /// </summary>
        /// <returns></returns>
        public IList<PER_ActionPermissions> GetAllActionPermissions()
        {
            return _IPER_ActionPermissionsRepo.GetAllActionPermissions();
        }
        /// <summary>
        /// 获取行为权限分组，用于界面操作的数据
        /// </summary>
        /// <returns></returns>
        public IList<PER_PermissionsGroup> GetAllPermissionsGroup()
        {
            return _IPER_PermissionsGroupRepo.GetAllPermissionsGroup();
        }

        //分配用户数据权限
        public IList<PER_DataPermissions> GetDataPermissionsByUserId(int userId)
        {
            return _IPER_DataPermissionsRepo.GetDataPermissionsByUserId(userId);
        }

        #region New

        public IEnumerable<SYS_Module> GetAuthorizedModules(AuthorizationOwnerTypeEnum ownerType, params int[] ownerIds)
        {
            return _ISYS_ModuleRepo.GetAuthorizedModules(ownerType, ownerIds);
        }

        public IEnumerable<SYS_ModuleFunction> GetAuthorizedFunctions(AuthorizationOwnerTypeEnum ownerType, params int[] ownerIds)
        {
            return _ISYS_ModuleFunctionRepo.GetAuthorizedFunctions(ownerType, ownerIds);
        }

        public IEnumerable<SYS_Module> GetUserAuthorizedModules(int userId)
        {
            var userRoles = _IPER_UserToRoleRepo.GetUserRoles(userId);
            if (userRoles.Any(a => a.RoleName.Equals(ConstData.SuperManagerRoleName)))
            {
                return _ISYS_ModuleRepo.GetAll(false);
            }
            else if (userRoles.Any(a => a.RoleName.Equals(ConstData.OrgManagerRoleName)))
            {
                return _ISYS_ModuleRepo.GetOrgManagerModules();
            }
            else
            {
                var roleIds = _IPER_UserToRoleRepo.GetUserRoleIds(userId);
                if (roleIds.Count() == 0) throw new NullReferenceException("未将角色分配给用户！");
                var roleModules = _ISYS_ModuleRepo.GetAuthorizedModules(AuthorizationOwnerTypeEnum.Role, roleIds.ToArray()).Distinct();
                return roleModules;
            }
        }

        public IEnumerable<SYS_ModuleFunction> GetUserAuthorizedFunctions(int userId)
        {
            var userRoles = _IPER_UserToRoleRepo.GetUserRoles(userId);
            if (userRoles.Any(a => a.RoleName.Equals(ConstData.SuperManagerRoleName)))
            {
                return _ISYS_ModuleFunctionRepo.GetAll(false);
            }
            else if (userRoles.Any(a => a.RoleName.Equals(ConstData.OrgManagerRoleName)))
            {
                return _ISYS_ModuleFunctionRepo.GetOrgManagerModuleFunctions();
            }
            else
            {
                var roleIds = _IPER_UserToRoleRepo.GetUserRoleIds(userId);
                var roleFunctions = _ISYS_ModuleFunctionRepo.GetAuthorizedFunctions(AuthorizationOwnerTypeEnum.Role, roleIds.ToArray()).Distinct();
                return roleFunctions;
            }
        }

        public IEnumerable<PER_DataAuthorization> GetDataAuthorization(AuthorizationOwnerTypeEnum ownerType, params int[] ownerIds)
        {
            return _IPER_DataAuthorizationRepo.GetDataAuthorization(ownerType, ownerIds);
        }

        #endregion
    }
}
